//
//  ScreenRasterDocument.m
//  Screen_Raster2
//
//  Created by Tianzhou on 08-11-5.
//  Copyright Tianzhou Software Inc. 2008 . All rights reserved.
// 
//   Licensed under the Apache License, Version 2.0 (the "License"); you may not
//   use this file except in compliance with the License.  You may obtain a copy
//   of the License at
//  
//   http://www.apache.org/licenses/LICENSE-2.0
// 
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
//   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
//   License for the specific language governing permissions and limitations under
//   the License.
//

#import "ScreenRasterDocument.h"
#import "ScreenRasterOverlayScreenWindow.h"
#import "ScreenRasterTransparentView.h"

#import "ScreenRaster.h"
#import "ScreenRasterPreferenceKeys.h"
#import "ScreenRasterConfigureData.h"

static NSString *const kPrefsToWatch[] =
{
	kScreenRasterLineIntervalKey,
	kScreenRasterLineWidthKey,
	kScreenRasterLineAlphaValueKey,
    kScreenRasterFontSizeKey,
    kScreenRasterCharacterSpacingKey,
    kScreenRasterShowPositionKey,
    kScreenRasterShowEdgeKey,
	kScreenRasterLineColorKey,
	kScreenRasterPlotEdgeColorKey,
	kScreenRasterPlotEdgeTextColorKey,
	kScreenRasterMousePointColorKey,
	kScreenRasterShowVerticalRasterLineKey,
	kScreenRasterShowHorizontalRasterLineKey
};

@interface ScreenRasterDocument(private_method)
- (NSString*)valuesKey:(NSString*)key;
@end


@implementation ScreenRasterDocument

- (NSString*)valuesKey:(NSString*)key {
	return [NSString stringWithFormat:@"values.%@", key];
}

+ (void)initialize
{
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
	NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
								 [NSNumber numberWithFloat:kScreenRasterDefaultLineInterval],
								 kScreenRasterLineIntervalKey,
								 [NSNumber numberWithFloat:kScreenRasterDefaultLineWidth],
								 kScreenRasterLineWidthKey,
								 [NSNumber numberWithFloat:kScreenRasterDefaultLineAlphaValue],
								 kScreenRasterLineAlphaValueKey,
								 [NSNumber numberWithInt:kScreenRasterDefaultFontSize],
								 kScreenRasterFontSizeKey,
								 [NSNumber numberWithInt:kScreenRasterDefaultCharacterSpacing],
								 kScreenRasterCharacterSpacingKey,
								 [NSNumber numberWithBool:kScreenRasterDefaultShowPositionKey],
								 kScreenRasterShowPositionKey,
								 [NSNumber numberWithBool:kScreenRasterDefaultShowEdgeKey],
								 kScreenRasterShowEdgeKey,
	                             [NSArchiver archivedDataWithRootObject:[NSColor redColor]],
	                             kScreenRasterLineColorKey,
	                             [NSArchiver archivedDataWithRootObject:[NSColor blueColor]],
	                             kScreenRasterPlotEdgeColorKey,
	                             [NSArchiver archivedDataWithRootObject:[NSColor grayColor]],
								 kScreenRasterPlotEdgeTextColorKey,
								 [NSArchiver archivedDataWithRootObject:[NSColor blackColor]],
								 kScreenRasterMousePointColorKey,
								 [NSNumber numberWithBool:YES],
								 kScreenRasterShowVerticalRasterLineKey,
								 [NSNumber numberWithBool:YES],
								 kScreenRasterShowHorizontalRasterLineKey,
	                             nil];
	                             
	
	[defaults registerDefaults:appDefaults]; 
	
}

- (id)init
{
    self = [super init];
    if (self) {
    
        // Add your subclass-specific initialization here.
        // If an error occurs here, send a [self release] message and return nil.
    
    }
    return self;
}

- (void)awakeFromNib
{
	NSUserDefaultsController *defaults = [NSUserDefaultsController sharedUserDefaultsController];
	size_t i;
	for ( i = 0; i < sizeof(kPrefsToWatch) / sizeof(NSString*); ++i)
	{
		[defaults addObserver:self
	              forKeyPath:[self valuesKey:kPrefsToWatch[i]]
					 options:NSKeyValueObservingOptionNew
					 context:nil];
	}
}


- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context
{
	if ([object isEqualTo:[NSUserDefaultsController sharedUserDefaultsController]])
	{
		[mOverlayScreenWindow display];
	}
}

- (NSString *)windowNibName
{
    // Override returning the nib file name of the document
    // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
    return @"ScreenRasterDocument";
}

- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
    [super windowControllerDidLoadNib:aController];
    // Add any code here that needs to be executed once the windowController has loaded the document's window.
}

- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
    // Insert code here to write your document to data of the specified type. If the given outError != NULL, ensure that you set *outError when returning nil.

    // You can also choose to override -fileWrapperOfType:error:, -writeToURL:ofType:error:, or -writeToURL:ofType:forSaveOperation:originalContentsURL:error: instead.

    // For applications targeted for Panther or earlier systems, you should use the deprecated API -dataRepresentationOfType:. In this case you can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.

    if ( outError != NULL ) {
		*outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
	}
	return nil;
}

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
{
    // Insert code here to read your document from the given data of the specified type.  If the given outError != NULL, ensure that you set *outError when returning NO.

    // You can also choose to override -readFromFileWrapper:ofType:error: or -readFromURL:ofType:error: instead. 
    
    // For applications targeted for Panther or earlier systems, you should use the deprecated API -loadDataRepresentation:ofType. In this case you can also choose to override -readFromFile:ofType: or -loadFileWrapperRepresentation:ofType: instead.
    
    if ( outError != NULL ) {
		*outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL];
	}
    return YES;
}

- (IBAction)goFullScreen:(id)sender
{
    // Get the screen information.
    NSScreen* mainScreen = [NSScreen mainScreen];
    NSDictionary* screenInfo = [mainScreen deviceDescription];
    NSNumber* screenID = [screenInfo objectForKey:@"NSScreenNumber"];
	
    // Capture the screen.
    CGDirectDisplayID displayID = (CGDirectDisplayID)[screenID longValue];
    CGDisplayErr err = CGDisplayCapture(displayID);
    if (err == CGDisplayNoErr)
    {
        // Create the full-screen window if it doesn’t already  exist.
        if (!mFullScreenModeWindow)
        {
            // Create the full-screen window.
            NSRect winRect = [mainScreen frame];
            mFullScreenModeWindow = [[NSWindow alloc] initWithContentRect:winRect
														 styleMask:NSBorderlessWindowMask
														   backing:NSBackingStoreBuffered
															 defer:NO
															screen:[NSScreen mainScreen]];
			
            // Establish the window attributes.
			[mFullScreenModeWindow setBackgroundColor: [NSColor colorWithCalibratedWhite:1 alpha:0]];
            [mFullScreenModeWindow setReleasedWhenClosed:NO];
            [mFullScreenModeWindow setDisplaysWhenScreenProfileChanges:YES];
            [mFullScreenModeWindow setDelegate:self];
			
            // Create the custom view for the window.
            ScreenRasterTransparentView* theView = [[ScreenRasterTransparentView alloc]
										 initWithFrame:winRect];
            [mFullScreenModeWindow setContentView:theView];
            [theView setNeedsDisplay:YES];
            [theView release];
        }
		
        // Make the screen window the current document window.
        // Be sure to retain the previous window if you want to  use it again.
        NSWindowController* winController = [[self windowControllers]
											 objectAtIndex:0];
        [winController setWindow:mFullScreenModeWindow];
		
        // The window has to be above the level of the shield window.
        int32_t     shieldLevel = CGShieldingWindowLevel();
        [mFullScreenModeWindow setLevel:shieldLevel];
		
        // Show the window.
        [mFullScreenModeWindow makeKeyAndOrderFront:self];
    }
}

@end
